package com.example.hinfc;

import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class PosActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback {
    private static final String TAG = "PosActivity";
    private static final String AID = "F0010203040506";
    private View mobilePosBackView =  null;
    private EditText amountView =  null;
    private View confirmView = null;
    private NfcAdapter nfcAdapter;

//    private TextView etAmount;
//    private Button  btnStart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate success");

        setContentView(R.layout.mobile_pos_activity);
        this.mobilePosBackView = findViewById(R.id.mobile_pos_back_icon);
        this.mobilePosBackView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        this.amountView = findViewById(R.id.mobule_pos_input);
        this.confirmView = findViewById(R.id.mobile_pos_confime);
        this.confirmView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "OnClick....");
                enableNfcReader();
            }
        });

//        setContentView(R.layout.reader_activity);
//        etAmount = findViewById(R.id.tvNumber);
//        btnStart = findViewById(R.id.btnRead);
//        btnStart.setOnClickListener(v -> {
//            String amount = etAmount.getText().toString();
//            if (!amount.isEmpty()) {
//                enableNfcReader();
//            }
//            Log.d(TAG, "OnClick....");
//            enableNfcReader();
//        });
    }

    private void enableNfcReader() {
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (nfcAdapter != null) {
            nfcAdapter.enableReaderMode(this, this,
                NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
                null);
        }
    }

    @Override
    public void onTagDiscovered(Tag tag) {
        Log.i(TAG, "onTagDiscovered");
        IsoDep isoDep = IsoDep.get(tag);
        try {
            isoDep.connect();
            Log.i(TAG, "isoDep.connect()");

            // SELECT AID
            byte[] selectCommand = buildSelectApdu(AID);
            byte[] response = isoDep.transceive(selectCommand);
            Log.i(TAG, "response = " + Arrays.toString(response));

            if (isSuccess(response)) {
                String amount = amountView.getText().toString();
                if (!amount.isEmpty()) {
                    Log.i(TAG, "amount = " + amount);
                } else {
                    Log.i(TAG, "amount.isEmpty()!!!");
                    Toast.makeText(this, "amount is empty!!!", Toast.LENGTH_SHORT).show();
                }

                // PAYMENT
                byte[] paymentCommand = buildPaymentApdu(amount.getBytes());
                Log.i(TAG, "paymentCommand = " + Arrays.toString(paymentCommand));

                response = isoDep.transceive(paymentCommand);

                byte[] finalResponse = response;
                runOnUiThread(() -> {
                    if (isSuccess(finalResponse)) {
                        Log.i(TAG, "amount = " + amount);
                        Toast.makeText(this, "Received Successfully!! Amount = " + amount, Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(this, "Receive Failed!!! Amount = " + amount, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "error : " + e.getMessage());
        } finally {
            try {
                isoDep.close();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, "error : " + e.getMessage());
            }
        }
    }

    private byte[] buildSelectApdu(String aid) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        stream.write(0x00); // CLA
        stream.write(0xA4); // INS
        stream.write(0x04); // P1
        stream.write(0x00); // P2
        stream.write(aid.length() / 2); // Lc
        stream.write(hexStringToByteArray(aid), 0, aid.length() / 2);
        stream.write(0x00); // Le
        return stream.toByteArray();
    }

    private byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

    private boolean isSuccess(byte[] response) {
        return response.length >= 2 &&
                (response[response.length - 2] & 0xFF) == 0x90 &&
                (response[response.length - 1] & 0xFF) == 0x00;
    }

    private byte[] buildPaymentApdu(byte[] amountBytes) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();

        // APDU 结构
        stream.write(0x00);    // CLA: 通用标签
        stream.write(0xB0);    // INS: 自定义支付指令（需与HCE端约定）
        stream.write(0x00);    // P1: 参数1
        stream.write(0x00);    // P2: 参数2
        stream.write(amountBytes.length); // Lc: 数据长度
        stream.write(amountBytes, 0, amountBytes.length); // 交易金额数据
        stream.write(0x00);    // Le: 期望响应长度

        return stream.toByteArray();
    }
}
